package org.folio.rest.impl.pojo;

import io.vertx.core.AsyncResult;
import io.vertx.core.Future;
import io.vertx.core.Handler;
import io.vertx.core.Vertx;
import io.vertx.core.logging.Logger;
import io.vertx.core.logging.LoggerFactory;
import org.folio.rest.impl.other.take.TakeInterface;
import org.folio.rest.persist.PostgresClient;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

public class WebPartyViews implements TakeInterface {
    private final static Logger logger = LoggerFactory.getLogger("modparty");
    private static Vertx vertx =null;
    private static String tenant =null;;
    private static  ConcurrentHashMap<String, AtomicInteger> intCounter = new ConcurrentHashMap<String, AtomicInteger >();



    public WebPartyViews(Vertx vertx,String tenant) {
        this.vertx = vertx;
        this.tenant = tenant;
    }
    @Override
    public void setIntCounter(String partyId, Handler<AsyncResult<Integer>> asyncResultHandler) {
        Future<Integer> future =Future.future();
        AtomicInteger value = intCounter.get(partyId);
        if (value !=null){
            Integer result = value.incrementAndGet();
            future.complete(result);

        }else{

            PostgresClient.getInstance( vertx, tenant).getById("party_view_amount",partyId,PartyViewAmount.class,
                     reply->{
               if (reply.succeeded()){
                   PartyViewAmount  result = reply.result() ;
                   int viewAmount = result.getViewAmount() + 1;

                   intCounter.put(partyId, new AtomicInteger(viewAmount));
                   future.complete(viewAmount);
                   return;
               }else{
                   intCounter.put(partyId, new AtomicInteger(1));
                   future.complete(1);
                   return;
               }
            });


        }
        future.setHandler(re->{
            if (re.succeeded()){
                asyncResultHandler.handle(Future.succeededFuture(re.result()));
            }else {
                asyncResultHandler.handle(Future.failedFuture(re.cause()));
            }
        });
    }
    @Override
    public   Integer getIntCounter(String partyId){
        AtomicInteger value = intCounter.get(partyId);
        if (value == null){
            return 0;
        }
        return value.get();
    }

    private static void saveOrUpdate(){
        intCounter.forEach((a,b)->{
            PostgresClient pg = PostgresClient.getInstance(vertx, tenant);
            pg.getById("party_view_amount",a,PartyViewAmount.class,reply->{
                    if (reply.succeeded()){
                        PartyViewAmount result = reply.result();
                        if (result !=null){
                            result.setViewAmount( result.getViewAmount()+b.get());
                            pg.update("party_view_amount",result,result.getId(),null);
                        }else {
                            result = new PartyViewAmount();
                            result.setViewAmount(b.get());
                            result.setId(a);
                            result.setPartyId(a);
                            pg.save("party_view_amount",result.getId(),result,null);
                        }

                    }else
                    {
                        logger.info(reply.cause());
                    }
                });
        });
    }

    @Override
    public void timeTake() {
     saveOrUpdate();
    }
}
